package com.echo.im.repository.offline.support;

import com.echo.im.common.contant.RedisConstants;
import com.echo.im.common.model.mq.OfflineMsgMqInfo;
import com.echo.im.repository.dao.entity.SystemMessage;
import com.echo.im.repository.dao.mapper.SystemMessageMapper;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 系统消息离线管理器
 * @author echo
 */
@Component
public class SystemOfflineService extends AbstractOfflineService<SystemMessage> {

    private static final int MAX_OFFLINE_MESSAGES = 1000; // 最大离线消息数
    private static final int MESSAGES_TO_DELETE = 200; // 每次删除的旧消息数量
    private static final int MESSAGE_EXPIRATION_DAYS = 30; // 消息过期时间

    private final SystemMessageMapper systemMessageMapper;
    private final MySQLOfflineStorage mySQLStorage;
    private final RedisOfflineStorage redisStorage;

    public SystemOfflineService(MySQLOfflineStorage mysqlStorage,
                                DistributedLockManager lockManager,
                                SystemMessageMapper systemMessageMapper,
                                RedisOfflineStorage redisStorage) {
        super(lockManager,redisStorage);
        this.mySQLStorage = mysqlStorage;
        this.systemMessageMapper = systemMessageMapper;
        this.redisStorage = redisStorage;
    }

    @Override
    protected String getRedisKeyPrefix() {
        return RedisConstants.IM_SYSTEM_OFFLINE_STORE+":";
    }

    @Override
    protected List<SystemMessage> fetchAndDeleteMessagesFromStorage(Long userId, Long lastFetchedMessageId, int fetchLimit) {
        List<SystemMessage> messages = new ArrayList<>();

        // 1. 如果传入了 lastMsgId，则删除该 ID 之前的消息
        if (!lastFetchedMessageId.equals(0L)) {
            redisStorage.deleteMessageIds(getRedisKeyPrefix() + userId, lastFetchedMessageId);
            // 如果需要的话，删除 MySQL 中的消息
            mySQLStorage.deleteMessageIds(userId, lastFetchedMessageId);
        }

        // 2. 从 Redis 中增量拉取 msgIds
        List<String> redisMsgIds = redisStorage.getMessageIds(getRedisKeyPrefix() + userId, lastFetchedMessageId, fetchLimit);
        if (!redisMsgIds.isEmpty()) {
            // 从 SystemMessage 表中查询消息内容
            List<SystemMessage> redisMessages = systemMessageMapper.selectBatchIds(redisMsgIds);
            messages.addAll(redisMessages);
        }

        return messages;
    }

    @Override
    protected void doStoreMessage(Long userId, String redisKey, Long msgId) {
        // 增量添加消息到 Redis
        redisStorage.addMessageId(redisKey, msgId, MESSAGE_EXPIRATION_DAYS, TimeUnit.DAYS);

        // 获取 Redis 中消息的数量
        Long currentMessageCount = getOfflineMessageCount(userId);

        // 如果超过最大消息数，删除最旧的200条消息
        if (currentMessageCount != null && currentMessageCount > MAX_OFFLINE_MESSAGES) {
            redisStorage.deleteOldMessage(redisKey, MESSAGES_TO_DELETE - 1);
        }
    }

    @Override
    public boolean support(Integer code) {
        return OfflineMsgMqInfo.OfflineMsgEnum.SYSTEM_OFFLINE_MESSAGE.code().equals(code);
    }
}
